package com.custom.base.config

import android.content.Context
import android.content.SharedPreferences
import android.graphics.Color
import com.custom.base.R
import com.custom.base.entity.OkHttpBodyEntity
import com.custom.base.http.OkHttpManager
import com.custom.base.type.HeadConditionType
import com.custom.base.util.GosnUtil

/**
 * 作者：
 * 时间：2021/1/13
 * 描述：配置
 **/
class BaseConfig{
    private var sharedPreferences: SharedPreferences? = null
    private var context:Context? = null
    private val PAGE_NAME = "base_page_name"
    private val PAGE_SIZE_NAME = "base_page_size_name"
    private val CODE = "base_success_code"
    private val CODE_NAME = "base_success_code_name"
    private val MSG_NAME = "base_success_msg"
    private val DEBUG = "base_debug"
    private val ISLOG = "base_isLog"
    private val URL = "base_url"
    private val HEAD = "base_head"
    private val URLDECODER = "URLDecoder"
    private val URL_DEBUG = "base_url_debug"
    private val HTTP_CODE_URL_NO_CONTAIN = "base_http_code_url_no_contain"
    private val TITLE_BG_COLOR = "base_title_bg_color"
    private val TITLE_BACK_IV = "base_title_back_iv"
    private val TITLE_RIGHT_TV_COLOR = "base_title_right_tv_color"
    private val FORM_DATA_TYPE = "form_data_type"
    private val HTTP_FAIL_TOAST = "http_fail_toast"
    private val TITLE_BOLD = "title_bold"

    /**
     * 初始化
     * @param context
     * @param debug 是否是debug模式
     * @param printLog 是否打印日志
     * @param debugUrl debug模式下的请求接口
     * @param url 请求接口
     * @param successCode 请求正确的 code
     * @param successCodeName 请求正确的 code 名称
     * @param successMsgName 请求正确的 msg 名称
     * @param pageName 分页当前页 名称
     * @param pageSizeName 分页每页数据 名称
     * @param URLDecoder 请求结果是否URLDecoder解码
     * @param isHttpFailToast 请求失败时是否提示
     * @param titleColor title背景颜色
     * @param titleRightTvColor title右边文字颜色
     * @param titleBackIv title返回键
     * @param httpCodeUrlNoContain 全局监听请求去除URL包含的关键字
     * @param titleBold 标题加粗
     */
    fun init(
        context:Context,
        debug:Boolean = true,
        printLog:Boolean = true,
        debugUrl:String = "",
        url:String = "",
        fromDataType: OkHttpBodyEntity.TYPE = OkHttpBodyEntity.TYPE.RAW,
        successCode:String = "200",
        successCodeName:String = "code",
        successMsgName:String = "msg",
        pageName:String = "pageNo",
        pageSizeName:String = "pageSize",
        URLDecoder:Boolean = true,
        isHttpFailToast:Boolean = true,
        titleBold:Boolean = false,
        titleColor:Int = Color.parseColor("#ffffff"),
        titleRightTvColor:Int = Color.parseColor("#333333"),
        titleBackIv:Int = R.drawable.icon_back_black,
        httpCodeUrlNoContain:List<String> = listOf()
    ): BaseConfig {
        this.context = context
        sharedPreferences = context.getSharedPreferences("base_sp", Context.MODE_PRIVATE)
        setBoolean(ISLOG,debug)
        setBoolean(DEBUG,printLog)
        setBoolean(URLDECODER,URLDecoder)
        setBoolean(HTTP_FAIL_TOAST,isHttpFailToast)
        setString(URL,url)
        setString(URL_DEBUG,debugUrl)
        setString(CODE,successCode)
        setString(CODE_NAME,successCodeName)
        setString(MSG_NAME,successMsgName)
        setString(PAGE_NAME,pageName)
        setString(PAGE_SIZE_NAME,pageSizeName)
        setString(HTTP_CODE_URL_NO_CONTAIN, GosnUtil.object2Json(httpCodeUrlNoContain))
        setInt(TITLE_BG_COLOR,titleColor)
        setInt(TITLE_RIGHT_TV_COLOR,titleRightTvColor)
        setInt(TITLE_BACK_IV,titleBackIv)
        setBoolean(TITLE_BOLD,titleBold)
        setFromDataType(fromDataType)
//        val head = getString(HEAD,"")
//        if(head!=""){
//            val list: MutableMap<String,String> = Gson().fromJson(head, object : TypeToken<MutableMap<String,String>?>() {}.type)
//            OkHttpManager.instance.headModel = list
//        }
        return this
    }

    /**
     * 添加head
     * @param key
     * @param value
     * @param conditionKey 限制条件
     * @param conditionValue 限制内容
     */
    fun addHead(
        key: String,
        value: String,
        conditionKey: HeadConditionType = HeadConditionType.DEFAULT,
        conditionValue: String = ""
    ): BaseConfig {
        OkHttpManager.instance.headModel[key] = value
        setString(HEAD, GosnUtil.object2Json(OkHttpManager.instance.headModel))
        return this
    }

    /**
     * 删除 head
     * @param key
     */
    fun removeHead(key: String){
        val iterator = OkHttpManager.instance.headModel.iterator()
        while (iterator.hasNext()){
            val baseHeadModel = iterator.next()
            if(baseHeadModel.key == key) iterator.remove()
        }
        setString(HEAD, GosnUtil.object2Json(OkHttpManager.instance.headModel))
    }

    /**
     * 是否可以打印日志
     */
    fun isLog(): Boolean {
        return getBoolean(ISLOG,true)
    }

    /**
     * 请求正确的 code
     */
    fun getSuccessCode(): String {
        return getString(CODE,"200")
    }
    /**
     * 请求正确的 code 名称
     */
    fun getSuccessCodeName(): String {
        return getString(CODE_NAME,"code")
    }
    /**
     * 请求msg 名称
     */
    fun getSuccessMsgName(): String {
        return getString(MSG_NAME,"msg")
    }
    /**
     * 分页当前页 名称
     */
    fun getPageName(): String {
        return getString(PAGE_NAME,"pageNo")
    }
    /**
     * 分页每页数据 名称
     */
    fun getPageSizeName(): String {
        return getString(PAGE_SIZE_NAME,"pageSize")
    }
    /**
     * 获取请求地址
     */
    fun getUrl(): String {
        return if(getBoolean(DEBUG,true)) getString(URL_DEBUG,"")
        else getString(URL,"")
    }

    /**
     * 设置URL
     */
    fun setUrl(url:String){
        if(getBoolean(DEBUG,true)) setString(URL_DEBUG,url)
        else setString(URL,url)
    }
    /**
     * title颜色
     */
    fun getTitleBgColor(): Int {
        return getInt(TITLE_BG_COLOR,Color.parseColor("#ffffff"))
    }
    /**
     * title右边文字颜色
     */
    fun getTitleRightTvColor(): Int {
        return getInt(TITLE_RIGHT_TV_COLOR,Color.parseColor("#333333"))
    }
    /**
     * title返回键
     */
    fun getTitleBack(): Int {
        return getInt(TITLE_BACK_IV,R.drawable.icon_back_black)
    }
    /**
     * 全局监听请求去除URL包含的关键字
     */
    fun getHttpCodeUrlNoContain(): List<String> {
        val listStr = getString(HTTP_CODE_URL_NO_CONTAIN,"")
        if(listStr == "") return listOf()
        return GosnUtil.json2List(listStr,String::class.java)
    }

    /**
     * 请求结果是否URLDecoder解码
     */
    fun isURLDecoder(): Boolean {
        return getBoolean(URLDECODER,true)
    }

    /**
     * 请求失败是否提示
     */
    fun isHttpFailToast(): Boolean {
        return getBoolean(HTTP_FAIL_TOAST,true)
    }
    /**
     * 标题是否加粗
     */
    fun isTitleBold(): Boolean {
        return getBoolean(TITLE_BOLD,false)
    }

    /**
     * 获取请求类型
     */
    fun getFromDataType(): OkHttpBodyEntity.TYPE {
        return if(getInt(FORM_DATA_TYPE,1) == 1) OkHttpBodyEntity.TYPE.RAW else OkHttpBodyEntity.TYPE.FORM_DATA
    }

    /**
     * 设置请求类型
     */
    fun setFromDataType(type:OkHttpBodyEntity.TYPE){
        when (type) {
            OkHttpBodyEntity.TYPE.RAW -> setInt(FORM_DATA_TYPE,1)
            OkHttpBodyEntity.TYPE.FORM_DATA -> setInt(FORM_DATA_TYPE,2)
        }
    }

    fun setBoolean(s: String, bool: Boolean) {
        sharedPreferences?.apply {
            val edit = this.edit()
            edit.putBoolean(s, bool)
            edit.apply()
        }
    }
    fun setString(s: String, str: String) {
        sharedPreferences?.apply {
            val edit = this.edit()
            edit.putString(s, str)
            edit.apply()
        }
    }

    fun setInt(s: String, it: Int) {
        sharedPreferences?.apply {
            val edit = this.edit()
            edit.putInt(s, it)
            edit.apply()
        }
    }

    fun setLong(s: String, lo: Long) {
        sharedPreferences?.apply {
            val edit = this.edit()
            edit.putLong(s, lo)
            edit.apply()
        }
    }

    fun setFlot(s: String, lo: Float){
        sharedPreferences?.apply {
            val edit = this.edit()
            edit.putFloat(s, lo)
            edit.apply()
        }
    }

    fun getFlot(s: String, flot: Float): Float {
        return sharedPreferences!!.getFloat(s, flot)
    }

    fun getBoolean(s: String, bool: Boolean): Boolean {
        return sharedPreferences!!.getBoolean(s, bool)
    }

    fun getString(s: String, str: String): String {
        return sharedPreferences!!.getString(s, str)!!
    }

    fun getInt(s: String, it: Int): Int {
        return sharedPreferences!!.getInt(s, it)
    }

    fun getLong(s: String, lo: Long): Long {
        return sharedPreferences!!.getLong(s, lo)
    }

    companion object {
        private var instance: BaseConfig? = null
        val getInstance: BaseConfig
            get() {
                if (instance == null) {                         //Single Checked
                    synchronized(BaseConfig::class.java) {
                        if (instance == null) {                 //Double Checked
                            instance =
                                BaseConfig()
                        }
                    }
                }
                return instance!!
            }
    }
}